package com.choupin.choupin.service.impl;

import com.choupin.choupin.entity.Lottery;
import com.choupin.choupin.entity.Member;
import com.choupin.choupin.entity.Order;
import com.choupin.choupin.entity.Paging;
import com.choupin.choupin.mapper.LotterypoolMapper;
import com.choupin.choupin.mapper.MemberMapper;
import com.choupin.choupin.mapper.OrderMapper;
import com.choupin.choupin.mapper.UserMapper;
import com.choupin.choupin.service.IOderService;
import com.choupin.choupin.service.exception.ParameterIsEmptyException;
import com.choupin.choupin.service.exception.SelectExcepion;
import com.choupin.choupin.service.exception.UpdateException;
import com.choupin.choupin.utils.redis.RedisHashUtil;
import com.choupin.choupin.utils.redis.RedisMessageQueue;
import com.choupin.choupin.utils.redis.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.awt.*;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.List;

@SuppressWarnings("ALL")
@Service
public class OderServiceImpl implements IOderService {

     @Autowired
     private LotterypoolMapper lotterypoolMapper;

     @Autowired
     private MemberMapper memberMapper;

     @Autowired
     private OrderMapper orderMapper;

     @Autowired
     private UserMapper userMapper;

     @Autowired
     private RedisUtils redisUtils;

    @Override
    public void createOrder(String phone, String name, Integer type,Integer memeberId) {
//       参数校验
        if (phone==null||type==null){
            throw new ParameterIsEmptyException("参数为空！");
        }
//       生成订单
        Order order=new Order();
//        当前时间
        LocalDateTime localDateTime=LocalDateTime.now();
//        增加30分钟
        LocalDateTime  newLocalDateTime=localDateTime.plusMinutes(30);
        if (type==0){
            //       查询抽奖池数据
            Lottery lottery=lotterypoolMapper.selectOneTopName(name);
            if (lottery==null){
                throw new SelectExcepion("抽奖池数据为空！");
            }
            order.setPhone(phone);
            order.setTypeId(lottery.getId());
            order.setType(type);
            order.setImage(lottery.getImage());
            order.setName(lottery.getName());
            order.setPrice(lottery.getPrice());
            order.setStartTime(localDateTime);
            order.setEndTime(newLocalDateTime);
            order.setStatus(0);
            order.setCreatedUser("管理员");
            order.setModifiedUser("管理员");
            order.setCreatedTime(localDateTime);
            order.setModifiedTime(localDateTime);
        }
        if (type==1){
            Member member=memberMapper.selectMemberUserOneId(memeberId);
            if (member==null){
             throw new SelectExcepion("会员不存在");
            }
            order.setPhone(phone);
            order.setTypeId(memeberId);
            order.setType(type);
            order.setImage(member.getIcon());
            order.setName(member.getName());
            order.setPrice(member.getPrice());
            order.setStartTime(localDateTime);
            order.setEndTime(newLocalDateTime);
            order.setStatus(0);
            order.setCreatedUser("管理员");
            order.setModifiedUser("管理员");
            order.setCreatedTime(localDateTime);
            order.setModifiedTime(localDateTime);
        }
//        生成订单
        if (order!=null&&order.getStatus()!=null){
            orderMapper.insertOder(order);
            System.out.println("--------订单生成成功！——————");
            System.out.println("order："+order);
            DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String startTime=order.getStartTime().format(dateTimeFormatter);
            RedisHashUtil.hset("orders_id","id_"+order.getId(),order.getId().toString());
            RedisHashUtil.hset("orders_time","startTime_"+order.getId(),startTime);
            RedisHashUtil.hset("orders_count","count_down_"+order.getId(),"29");
            System.out.println("--------订单存入Redis缓存表！——————");
        }
    }

    @Override
    public List<Order> showOrder(String phone,Integer currentPage,Integer pageSize) {
      if (phone==null){
          throw new ParameterIsEmptyException("参数错误！");
      }
      List<Order> orders=orderMapper.selectOrderOnePhone(phone,currentPage,pageSize);
      if (orders.size()<=0||orders==null){
          throw new SelectExcepion("用户订单不存在");
      }
        return orders;
    }

     @Transactional
    @Override
    public void updateOrder(Integer id,String phone) {
//        参数校验
      if (id==null){
          throw new ParameterIsEmptyException("参数为空");
      }
//      通过订单id查询订单数据
         Order order=orderMapper.selectOrderOneId(id);
      if (order==null){
          throw new SelectExcepion("查询异常！");
      }
//         通过id更新订单
      Integer result=orderMapper.updateOneId(id,1);
      if (result!=1||result==null){
          throw new UpdateException("更新数据异常！");
      }
         System.out.println("订单状态更新支付成！");
//        清空订单缓存数据
         RedisHashUtil.hdel("orders_id","id_"+id);
         RedisHashUtil.hdel("orders_time","startTime_"+id);
         RedisHashUtil.hdel("orders_count","count_down_"+id);
         System.out.println("更新订单数据后，清空hash表缓存！");
         //        如果是抽奖券订单更新用户抽奖次数
        if (order.getType()==0){
            Integer count=0;
            if (RedisUtils.getCommonValue("lottery_"+phone+"_"+order.getTypeId())!=null){
                count=  Integer.parseInt(RedisUtils.getValue("lottery_"+phone+"_"+order.getTypeId()));
                System.out.println("增加抽奖次数，从redis中获取是多少："+count);
            }
            count++;
            System.out.println("抽奖次数增加一之后是多少："+count);
//            将每个用户每个抽奖池的抽奖次数存入缓存
            redisUtils.addRedis("lottery_"+phone+"_"+order.getTypeId(),String.valueOf(count));
            System.out.println("抽奖次数存入缓存成功！");
        }

//        如果是开通会员则更新用户会员状态
         if (order.getType()==1){
             Member member=memberMapper.selectMemberUserOneId(order.getTypeId());
             if (member==null){
                 throw new SelectExcepion("会员不存在！");
             }
          Integer resultUser=userMapper.updateUserTheMemberAndWeight(phone,member.getId(),member.getAddWeight(),1);
             if (resultUser==null){
                 throw new UpdateException("更新用户会员状态异常！");
             }
             System.out.println("用户会员状态更新成功！");

         }


    }

   /*
   *  @Scheduled 定时5s轮询方法
   *  @ @Transactional 防止并发问题，添加事务
   * */
    @Scheduled(fixedRate = 40000)
    @Transactional
    @Override
    public void checkOrders() {
//        获取当前时间
        LocalDateTime localDateTime=LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//        获取Redis缓存订单数据
        Map<String,String> map=new HashMap<>();
        map=RedisHashUtil.hgetAll("orders_id");
        Iterator<Map.Entry<String,String>> iteratorId=map.entrySet().iterator();
//     遍历订单数据
        while (iteratorId.hasNext()){
            Map.Entry<String,String> rId=iteratorId.next();
            System.out.println("key："+rId.getKey()+",value:"+rId.getValue());
//            获取hash缓存时间
            String startTimestr=RedisHashUtil.hget("orders_time","startTime_"+rId.getValue());

//            startTimestr=""+startTimestr.substring(0,startTimestr.length());
            System.out.println(startTimestr);
//            转换时间计算时间差
            LocalDateTime startTime=LocalDateTime.parse(startTimestr,dateTimeFormatter);
            Duration duration=Duration.between(startTime,localDateTime);
//            订单超时
            if (duration.toMinutes()>30){
//                将状态更新到数据库
                orderMapper.updateOneId(Integer.parseInt(rId.getValue()),3);
//                清除Redis缓存
                RedisHashUtil.hdel("orders_id",rId.getKey());
                RedisHashUtil.hdel("orders_time","startTime_"+rId.getValue());
                RedisHashUtil.hset("orders_count","count_down_"+rId.getValue(),"0");
                System.out.println("订单超时->数据库状态更新成功->清除redis的hash表数据");
            }else {
                long countdown=30-duration.toMinutes();
//            倒计时时间写入缓存
                RedisHashUtil.hset("orders_count","count_down_"+rId.getValue(),String.valueOf(countdown));
                System.out.println("将倒计时剩余时间存入缓存"+RedisHashUtil.hget("orders_count","count_down_"+rId.getValue()));
            }
        }
    }

    @Override
    public Integer countDown(Integer id) {
        if (id==null){
            throw new ParameterIsEmptyException("参数为空");
        }
        String countdown=RedisHashUtil.hget("orders_count","count_down_"+id);
        if (countdown==null){
            return -1;
        }
        Integer result=Integer.parseInt(countdown);
        System.out.println("查出订单缓存"+countdown);
        if (result==0){
            return  -1;
        }
        return result;
    }


}
